package com.jvyou.app.ds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jvyou.app.common.domain.entity.User;
import com.jvyou.app.common.domain.model.PageResult;
import com.jvyou.app.common.enums.HttpCodeEnum;
import com.jvyou.app.common.exception.AppException;
import com.jvyou.app.common.utils.orm.WrapperTool;
import com.jvyou.app.common.utils.password.PasswordUtils;
import com.jvyou.app.ds.domain.dto.StudentDto;
import com.jvyou.app.ds.domain.entity.Lesson;
import com.jvyou.app.ds.domain.entity.LessonStudent;
import com.jvyou.app.ds.domain.entity.Student;
import com.jvyou.app.ds.mapper.LessonMapper;
import com.jvyou.app.ds.mapper.LessonStudentMapper;
import com.jvyou.app.ds.mapper.StudentMapper;
import com.jvyou.app.ds.mapper.UserMapper;
import com.jvyou.app.ds.service.StudentService;
import com.jvyou.app.ds.utils.login.LoginContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;


/**
 * 学员信息表(Student)表服务实现类
 *
 * @author 橘柚
 * @since 2025-04-17 15:30:09
 */
@Service("studentService")
@RequiredArgsConstructor
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    private final UserMapper userMapper;
    private final LessonStudentMapper lessonStudentMapper;
    private final StudentMapper studentMapper;
    private final LessonMapper lessonMapper;

    private QueryWrapper<Student> getWrapper(StudentDto studentDto) {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        WrapperTool.notEmptyEq(queryWrapper, "user_id", studentDto.getUserId());
        WrapperTool.notEmptyEq(queryWrapper, "enrollment_type", studentDto.getEnrollmentType());
        WrapperTool.notEmptyEq(queryWrapper, "learning_status", studentDto.getLearningStatus());
        WrapperTool.notEmptyEq(queryWrapper, "paid_status", studentDto.getPaidStatus());
        WrapperTool.notEmptyLike(queryWrapper, "name", studentDto.getName());
        return queryWrapper;
    }

    @Override
    public List<Student> listStudent(StudentDto studentDto) {
        return list(getWrapper(studentDto));
    }

    @Override
    public PageResult<Student> pageStudent(StudentDto studentDto) {
        IPage<Student> page = new Page<>(studentDto.getCurrent(), studentDto.getPageSize());
        page = page(page, getWrapper(studentDto));
        return PageResult.success(page);
    }

    @Override
    public Student addStudent(Student student) {
        // 1. 先创建一条用户信息
        User user = User.builder()
                .name(student.getName())
                .username(student.getPhone())
                .password(PasswordUtils.encode("123456"))
                .nickname(student.getName())
                .phone(student.getPhone())
                .idCard(student.getIdCard())
                .type("3")
                .build();
        userMapper.insert(user);
        userMapper.addRole(user.getId(), "1003");
        student.setUserId(user.getId());
        save(student);
        return student;
    }

    @Override
    public PageResult<Student> pageByLesson(StudentDto studentDto) {
        IPage<Student> page = new Page<>(studentDto.getCurrent(), studentDto.getPageSize());
        QueryWrapper<Student> ew = getWrapper(studentDto);
        ew.inSql("id", "select student_id from ds_lesson_student where status<>'3' and lesson_id = '" + studentDto.getLessonId() + "'");
        page = page(page, ew);
        List<Student> records = page.getRecords();
        for (Student student : records) {
            LambdaQueryWrapper<LessonStudent> lessonStudentEw = new LambdaQueryWrapper<>();
            lessonStudentEw.eq(LessonStudent::getStudentId, student.getId())
                    .eq(LessonStudent::getLessonId, studentDto.getLessonId());
            LessonStudent lessonStudent = lessonStudentMapper.selectOne(lessonStudentEw);
            if (lessonStudent == null) {
                continue;
            }
            student.setSignInStatus(lessonStudent.getStatus());
        }
        return PageResult.success(page);
    }

    @Override
    public Boolean arrive(Long lessonId, Long studentId) {
        LambdaUpdateWrapper<LessonStudent> ew = new LambdaUpdateWrapper<>();
        ew.eq(LessonStudent::getLessonId, lessonId)
                .eq(LessonStudent::getStudentId, studentId)
                .set(LessonStudent::getStatus, "2");
        return lessonStudentMapper.update(null, ew) > 0;
    }

    @Override
    public Boolean cancelLesson(Long lessonId) {
        Long userId = LoginContext.getUserId();
        Long studentId = studentMapper.getByUser(userId).getId();
        LambdaUpdateWrapper<LessonStudent> ew = new LambdaUpdateWrapper<>();
        ew.eq(LessonStudent::getLessonId, lessonId)
                .eq(LessonStudent::getStudentId, studentId)
                .set(LessonStudent::getStatus, "2");
        return lessonStudentMapper.delete(ew) > 0;
    }

    @Transactional
    @Override
    public Boolean signInLesson(Long lessonId, String password) {
        Long userId = LoginContext.getUserId();
        Long studentId = studentMapper.getByUser(userId).getId();

        Lesson lesson = lessonMapper.selectById(lessonId);
        if (lesson == null) {
            throw new AppException(HttpCodeEnum.DATA_NOT_EXIST, "签到失败，查询不到课程信息");
        }
        // 课程还未开始
        if (lesson.getStartTime().isAfter(LocalDateTime.now())) {
            throw new AppException(HttpCodeEnum.DATA_NOT_EXIST, "签到失败，课程还未开始");
        }
        LambdaQueryWrapper<LessonStudent> ew = new LambdaQueryWrapper<>();
        ew.eq(LessonStudent::getLessonId, lessonId)
                .eq(LessonStudent::getStudentId, studentId);
        LessonStudent lessonStudent = lessonStudentMapper.selectOne(ew);
        if (lessonStudent == null) {
            throw new AppException(HttpCodeEnum.DATA_NOT_EXIST, "签到失败，查询不到课程预约信息");
        }
        if (lessonStudent.getStatus().equals("2")) {
            throw new AppException(HttpCodeEnum.DATA_EXIST, "签到失败，您已签到");
        }
        // 比较密码
        if (!lesson.getPassword().equals(password.trim())) {
            throw new AppException(HttpCodeEnum.DATA_NOT_EXIST, "签到失败，密码错误");
        }
        lessonStudent.setStatus("2");
        lessonStudentMapper.updateById(lessonStudent);
        return true;
    }
}
